package com.syf.core.service.context;

import com.syf.core.service.SyServiceDefinition;
import lombok.Data;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

@Data
public class ServiceRequest<T> implements Serializable {
    /***
     * 请求头数据
     * */
    @Valid
    @NotNull(message = "head object of ServiceRequest must be not null")
    private Head head;

    /**
     * 请求数据对象
     */
    @Valid
    private T dataObj;

    protected ServiceRequest(Map<String, Object> headItems) {
        this.head = new Head(headItems);
    }

    public ServiceRequest(String callingAppCompName) {
        this.head = new Head(callingAppCompName);
    }

    public ServiceRequest(String callingAppCompName, T dataObj) {
        this.head = new Head(callingAppCompName);
        this.dataObj = dataObj;
    }

    public ServiceRequest clone() {
        ServiceRequest newInstance = new ServiceRequest(this.getHead().getHeadItems());
        newInstance.getHead().setTraceId(this.getHead().getTraceId());
        newInstance.getHead().setCallCount(this.getHead().getCallCount());
        newInstance.getHead().setBizUseId(this.getHead().getBizUseId());
        newInstance.getHead().setBizOrderNo(this.getHead().getBizOrderNo());
        return newInstance;
    }

    @Data
    public class Head {
        /**
         * 调用的app component name
         */
        private String callingAppCompName;

        /**
         * 参数Map
         */
        private Map<String, Object> headItems;

        /**
         * 日志打印的链路跟踪号
         */
        private String traceId;

        /**
         * 调用计数
         */
        private Integer callCount = 0;

        /**
         * 业务订单号，如有
         */
        private String bizOrderNo;

        /**
         * 业务用户编号，如有
         */
        private String bizUseId;

        private SyServiceDefinition serviceDefinition;

        public Head() {
        }

        public Head(String callingAppCompName) {
            this(callingAppCompName, new HashMap<>());
        }

        public Head(String callingAppCompName, Map<String, Object> headItems) {
            this.callingAppCompName = callingAppCompName;
            this.headItems = headItems;
        }

        protected Head(Map<String, Object> headItems) {
            this.headItems = headItems;
        }
    }
}
